package cn.chengpengper.netdisk.component;

import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.Bucket;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.services.s3.model.S3ObjectSummary;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.IOUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import java.util.List;

@Slf4j
@Component
public class MinIOFileStoreEngine implements StoreEngine {

    @Resource
    private AmazonS3Client s3Client;

    /**
     * 检查存储桶是否存在
     * 
     * @param bucketName 存储桶名称
     * @return 如果存储桶存在返回true，否则返回false
     */
    @Override
    public boolean bucketExists(String bucketName) {
        if (bucketName == null || bucketName.isEmpty()) {
            return false;
        }
        return s3Client.doesBucketExist(bucketName);
    }

    /**
     * 删除存储桶
     * 
     * @param bucketName 存储桶名称
     * @return 如果成功删除存储桶返回true，否则返回false
     */
    @Override
    public boolean removeBucket(String bucketName) {
        if (bucketName == null || bucketName.isEmpty()) {
            log.warn("Bucket name is null or empty");
            return false;
        }
        try {
            if (!bucketExists(bucketName)) {
                log.info("Bucket name: {} does not exist", bucketName);
                return false;
            }

            List<S3ObjectSummary> objects = listObjects(bucketName);
            if (objects != null && !objects.isEmpty()) {
                log.warn("Bucket name: {} is not empty, cannot delete", bucketName);
                return false;
            }

            s3Client.deleteBucket(bucketName);
            boolean exists = bucketExists(bucketName);
            if (exists) {
                log.error("Failed to delete bucket: {}", bucketName);
                return false;
            }
            log.info("Bucket name: {} deleted successfully", bucketName);
            return true;
        } catch (Exception e) {
            log.error("Error deleting bucket: {}", bucketName, e);
            return false;
        }
    }

    /**
     * 创建存储桶
     * 
     * @param bucketName 存储桶名称
     */
    @Override
    public void createBucket(String bucketName) {
        if (bucketName == null || bucketName.isEmpty()) {
            log.warn("Bucket name is null or empty");
            return;
        }
        if (!bucketExists(bucketName)) {
            s3Client.createBucket(bucketName);
        }
    }

    /**
     * 获取所有存储桶
     * 
     * @return 存储桶列表
     */
    @Override
    public List<Bucket> getAllBucket() {
        return s3Client.listBuckets();
    }

    /**
     * 列出存储桶中的所有对象
     * 
     * @param bucketName 存储桶名称
     * @return 对象摘要列表
     */
    @Override
    public List<S3ObjectSummary> listObjects(String bucketName) {
        if (bucketName == null || bucketName.isEmpty()) {
            log.warn("Bucket name is null or empty");
            return List.of();
        }
        if (bucketExists(bucketName)) {
            return s3Client.listObjectsV2(bucketName).getObjectSummaries();
        }
        return List.of();
    }

    /**
     * 检查对象是否存在
     * 
     * @param bucketName 存储桶名称
     * @param objectKey 对象键
     * @return 如果对象存在返回true，否则返回false
     */
    @Override
    public boolean doesObjectExist(String bucketName, String objectKey) {
        if (bucketName == null || bucketName.isEmpty() || objectKey == null || objectKey.isEmpty()) {
            return false;
        }
        if (!bucketExists(bucketName)) {
            return false;
        }
        return s3Client.doesObjectExist(bucketName, objectKey);
    }

    /**
     * 上传本地文件到存储桶
     * 
     * @param bucketName 存储桶名称
     * @param objectKey 对象键
     * @param localFileName 本地文件路径
     * @return 如果上传成功返回true，否则返回false
     */
    @Override
    public boolean upload(String bucketName, String objectKey, String localFileName) {
        if (bucketName == null || bucketName.isEmpty() || 
            objectKey == null || objectKey.isEmpty() || 
            localFileName == null || localFileName.isEmpty()) {
            log.warn("Invalid parameters for upload");
            return false;
        }
        if (!bucketExists(bucketName)) {
            log.warn("Bucket does not exist: {}", bucketName);
            return false;
        }
        try {
            File file = new File(localFileName);
            // 检查文件是否存在以及是否为文件（而不是目录）
            if (!file.exists() || !file.isFile()) {
                log.warn("Local file does not exist or is not a file: {}", localFileName);
                return false;
            }
            s3Client.putObject(bucketName, objectKey, file);
            return true;
        } catch (Exception e) {
            log.error("Upload file has an exception:", e);
            return false;
        }
    }

    /**
     * 上传MultipartFile到存储桶
     * 
     * @param bucketName 存储桶名称
     * @param objectKey 对象键
     * @param file MultipartFile对象
     * @return 如果上传成功返回true，否则返回false
     */
    @Override
    public boolean upload(String bucketName, String objectKey, MultipartFile file) {
        if (bucketName == null || bucketName.isEmpty() || 
            objectKey == null || objectKey.isEmpty() || 
            file == null) {
            log.warn("Invalid parameters for upload");
            return false;
        }
        if (!bucketExists(bucketName)) {
            log.warn("Bucket does not exist: {}", bucketName);
            return false;
        }
        try (InputStream inputStream = file.getInputStream()) {
            ObjectMetadata metaData = new ObjectMetadata();
            metaData.setContentType(file.getContentType());
            metaData.setContentLength(file.getSize());
            s3Client.putObject(bucketName, objectKey, inputStream, metaData);
            return true;
        } catch (Exception e) {
            log.error("Upload file has an exception:", e);
            return false;
        }
    }

    /**
     * 删除存储桶中的对象
     * 
     * @param bucketName 存储桶名称
     * @param objectKey 对象键
     * @return 如果删除成功返回true，否则返回false
     */
    @Override
    public boolean delete(String bucketName, String objectKey) {
        if (bucketName == null || bucketName.isEmpty() || objectKey == null || objectKey.isEmpty()) {
            log.warn("Invalid parameters for delete");
            return false;
        }
        if (!bucketExists(bucketName)) {
            log.warn("Bucket does not exist: {}", bucketName);
            return false;
        }
        try {
            s3Client.deleteObject(bucketName, objectKey);
            log.info("Object deleted from bucket: {}, key: {}", bucketName, objectKey);
            return true;
        } catch (Exception e) {
            log.error("Error deleting object: {}/{}", bucketName, objectKey, e);
            return false;
        }
    }

    /**
     * 生成对象的下载URL
     * 
     * @param bucketName 存储桶名称
     * @param objectKey 对象键
     * @param timeout 过期时间
     * @param unit 时间单位
     * @return 下载URL，如果生成失败返回null
     */
    @Override
    public String getDownloadUrl(String bucketName, String objectKey, long timeout, TimeUnit unit) {
        if (bucketName == null || bucketName.isEmpty() || objectKey == null || objectKey.isEmpty()) {
            log.warn("Invalid parameters for generating download URL");
            return null;
        }
        if (!bucketExists(bucketName)) {
            log.warn("Bucket does not exist: {}", bucketName);
            return null;
        }
        try {
            Date expiration = new Date(System.currentTimeMillis() + unit.toMillis(timeout));
            String url = s3Client.generatePresignedUrl(bucketName, objectKey, expiration).toString();
            log.info("Generated download URL for object: {}/{}", bucketName, objectKey);
            return url;
        } catch (Exception e) {
            log.error("Error generating download URL for object: {}/{}", bucketName, objectKey, e);
            return null;
        }
    }

    /**
     * 将对象下载到HTTP响应中
     * 
     * @param bucketName 存储桶名称
     * @param objectKey 对象键
     * @param response HTTP响应对象
     */
    @Override
    public void download2Response(String bucketName, String objectKey, HttpServletResponse response) {
        if (bucketName == null || bucketName.isEmpty() || objectKey == null || objectKey.isEmpty()) {
            log.warn("Invalid parameters for download");
            return;
        }
        if (!bucketExists(bucketName)) {
            log.warn("Bucket does not exist: {}", bucketName);
            return;
        }
        try (S3Object s3Object = s3Client.getObject(bucketName, objectKey);
             OutputStream out = response.getOutputStream()) {
            String fileName = extractFileName(objectKey);
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            response.setContentType("application/force-download");
            response.setCharacterEncoding("UTF-8");

            IOUtils.copy(s3Object.getObjectContent(), out);
            log.info("File downloaded from bucket: {}, key: {}", bucketName, objectKey);
        } catch (IOException e) {
            log.error("Error downloading file from bucket: {}, key: {}", bucketName, objectKey, e);
        }
    }

    /**
     * 提取文件名，防止路径问题
     * 
     * @param objectKey 对象键
     * @return 文件名
     */
    private String extractFileName(String objectKey) {
        int lastSlashIndex = objectKey.lastIndexOf('/');
        if (lastSlashIndex >= 0 && lastSlashIndex < objectKey.length() - 1) {
            return objectKey.substring(lastSlashIndex + 1);
        }
        return objectKey;
    }
}
